﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using PumpLibrary;
using System.Globalization;
using System.Windows.Threading;
using System.Threading;
using PumpDisplay.PetroFexPumpServiceReference;


namespace PumpDisplay
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class PumpWindow : Window
    {
        PetroFexServiceClient client = new PetroFexServiceClient();
        CustomerGenerator m_CustomerGenerator;
        float dieselPrice, unleadedPrice;
        FuelType m_SelectedFuel;
        System.Timers.Timer timer = new System.Timers.Timer(250);

        private string m_PumpId;
        float m_ThisSale, m_LitresPumped;

        public PumpWindow(string pumpId)
        {
            InitializeComponent();
            m_PumpId = pumpId;
            m_CustomerGenerator = new CustomerGenerator(); //must be defined after ID to prevent customer becoming ready before an ID is created from server info.
            m_CustomerGenerator.CustomerReady += new CustomerGenerator.CustomerReadyHandler(CustomerReady);
            m_CustomerGenerator.PumpProgress += new CustomerGenerator.PumpProgressHandler(CustomerGeneratorPumpProgress);
            m_CustomerGenerator.PumpingFinished += new CustomerGenerator.PumpingFinishedHandler(CustomerGeneratorPumpingFinished);
            client.ConnectPump(m_PumpId);
            this.Title = "PetroFex Pump Display - Pump ID: " + m_PumpId;
            pumpIDLbl.Content = m_PumpId;
            List<float> prices = client.GetFuelPrices();

            unleadedPrice = prices[0];
            dieselPrice = prices[1];
            dieselPriceBox.Text = dieselPrice.ToString("N", new CultureInfo("en-GB"));
            unleadedPriceBox.Text = unleadedPrice.ToString("N", new CultureInfo("en-GB"));

            var updater = new ThreadStart(UpdateThisPump);
            updater.BeginInvoke(null, null);
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            client.DisconnectPump(m_PumpId);
        }

        void CustomerGeneratorPumpingFinished(object sender, EventArgs e)
        {
            client.UpdatePump(m_PumpId, m_LitresPumped, m_ThisSale);
            switch (m_SelectedFuel)
            {
                case (FuelType.Diesel):
                    client.LogCustomerPetrolPurchase("Diesel", m_LitresPumped, m_ThisSale);
                    Application.Current.Dispatcher.BeginInvoke(new Action(() => dieselPriceBox.Foreground = SystemColors.GrayTextBrush));
                    break;
                case (FuelType.Unleaded):
                    client.LogCustomerPetrolPurchase("Unleaded", m_LitresPumped, m_ThisSale);
                    Application.Current.Dispatcher.BeginInvoke(new Action(() => unleadedPriceBox.Foreground = SystemColors.GrayTextBrush));
                    break;
            }
            client.MakeCustomerUnready(m_PumpId);
            client.DeactivatePump(m_PumpId);
            timer.Start(); //start listening for activation again
        }

        void CustomerGeneratorPumpProgress(object sender, PumpProgressEventArgs e)
        {
            m_LitresPumped = (float)e.LitresPumped;
            m_ThisSale = 0.0f;
            Application.Current.Dispatcher.BeginInvoke(
                DispatcherPriority.Background,
                new Action(() => this.litresBox.Text = m_LitresPumped.ToString("N", new CultureInfo("en-GB"))));
            switch(m_SelectedFuel){
                case(FuelType.Diesel):
                    m_ThisSale = m_LitresPumped * dieselPrice;
                    Application.Current.Dispatcher.BeginInvoke(
                            new Action(() => thisSaleBox.Text = m_ThisSale.ToString("N", new CultureInfo("en-GB"))));
                    break;
                case(FuelType.Unleaded):
                    m_ThisSale = m_LitresPumped * unleadedPrice;
                    Application.Current.Dispatcher.BeginInvoke(
                            new Action(() => thisSaleBox.Text = m_ThisSale.ToString("N", new CultureInfo("en-GB"))));
                    break;
            }
            client.UpdatePump(m_PumpId, m_LitresPumped, m_ThisSale);
        }

        void CustomerReady(object sender, CustomerReadyEventArgs e)
        {
            m_SelectedFuel = e.SelectedFuel;
            switch (m_SelectedFuel)
            {
                case (FuelType.Diesel):
                    Application.Current.Dispatcher.BeginInvoke(new Action(() => dieselPriceBox.Foreground = Brushes.Red));
                    client.MakeCustomerReady(m_PumpId,"Diesel");
                    break;
                case (FuelType.Unleaded):
                    Application.Current.Dispatcher.BeginInvoke(new Action(() => unleadedPriceBox.Foreground = Brushes.Red));
                    client.MakeCustomerReady(m_PumpId,"Unleaded");
                    break;
            }
        }

        void StartPumping() 
        {
            m_CustomerGenerator.ActivatePump();
        }

        void UpdateThisPump()
        {
            timer.Elapsed += (sender, args) =>
                {
                    //make sure prices are always current
                    List<float> prices = client.GetFuelPrices();
                    unleadedPrice = prices[0];
                    dieselPrice = prices[1];
                    Application.Current.Dispatcher.BeginInvoke(new Action(() => dieselPriceBox.Text = dieselPrice.ToString("N", new CultureInfo("en-GB"))));
                    Application.Current.Dispatcher.BeginInvoke(new Action(() => unleadedPriceBox.Text = unleadedPrice.ToString("N", new CultureInfo("en-GB"))));

                    PetrolPump p = client.getPump(m_PumpId);
                    if (p.PumpActive && p.CustomerReady)
                    {
                        StartPumping();
                        timer.Stop();
                    }
                };
            timer.Start();
        }
    }
}
